package com.circle.interests.biz.core.category.wxredpackage;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.circle.interests.biz.core.protocol.RechargeResult;
import com.circle.interests.biz.enums.PrizeStatusEnum;
import com.circle.mar.api.dto.UserDto;
import com.circle.mar.api.service.DubboMarCloudUserService;
import com.circle.opencomponent.api.dto.UserInfoDto;
import com.circle.opencomponent.api.service.DubboAppletUserService;
import com.circle.pay.api.dto.RedPacketDto;
import com.circle.pay.api.dto.RedPacketResultDto;
import com.circle.pay.api.enums.EnumAccountSceneType;
import com.circle.pay.api.enums.EnumCallbackType;
import com.circle.pay.api.enums.EnumRedPacketStatus;
import com.circle.pay.api.enums.EnumRedPacketType;
import com.circle.pay.api.service.DubboPayAccountService;
import com.circle.trading.CircleTradingClient;
import com.circle.trading.vo.TradingApiResult;
import com.circle.trading.vo.TradingSendResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 微信红包（企业支付）
 *
 * @author zhou
 * @date 2021/12/8
 */
@Slf4j
@Component
public class PrizeWxRedPackageHandler {

    @DubboReference
    private DubboAppletUserService dubboAppletUserService;
    @DubboReference
    private DubboMarCloudUserService dubboMarCloudUserService;
    @Value("${circle.gateway.url}")
    private String gwUrl;
    @Value("${circle.gateway.appKey}")
    private String gwAppKey;
    @Value("${circle.gateway.appSecret}")
    private String gwAppSecret;
    @Value("${circle.merchant.code}")
    private String merchantCode;
    @Value("${circle.merchant.appId}")
    private String merchantAppId;
    @Value("${circle.service.groupId}")
    private String serviceGroupId;
    @DubboReference
    private DubboPayAccountService dubboPayAccountService;

    public RechargeResult recharge(String sceneId, String openId, String nickname, String phoneNumber, String payAppId, String payOpenId, Integer amount, String remark) {
        // 活动用户openId转支付公众号的openId
        RechargeResult rechargeResult = new RechargeResult();
        Integer redPacketType = EnumRedPacketType.GZH.getCode();
        if (StrUtil.isBlank(payAppId) || StrUtil.isBlank(payOpenId)) {
            payAppId = "wx6eb70b81ad9d0e34";
            UserInfoDto userInfoDto = dubboAppletUserService.getByOpenId(openId);
            if (userInfoDto != null) {
                if (StrUtil.isNotBlank(userInfoDto.getPayOpenId())) {
                    // 公众号用户需要查出微奖金appid和openid
                    userInfoDto = dubboAppletUserService.getByOpenId(userInfoDto.getPayOpenId());
                    if (userInfoDto != null) {
                        payAppId = userInfoDto.getAppId();
                        payOpenId = userInfoDto.getOpenId();
                    }
                } else {
                    // 小程序用户
                    payAppId = userInfoDto.getAppId();
                    payOpenId = userInfoDto.getOpenId();
                    redPacketType = EnumRedPacketType.MINI.getCode();
                    log.info("小程序用户:{}", JSONUtil.toJsonStr(userInfoDto));
                }
            } else {
                // 统一授权平台没有则去营销云查
                UserDto userDto = dubboMarCloudUserService.queryUserByOpenId(openId);
                log.info("从营销云获取用户 {} 信息:{}", openId, JSONUtil.toJsonStr(userDto));
                if (userDto != null && StrUtil.isNotBlank(userDto.getPayOpenId())) {
                    payOpenId = userDto.getPayOpenId();
                }
            }
            if (StrUtil.isBlank(payAppId) || StrUtil.isBlank(payOpenId)) {
                rechargeResult.setPrizeStatus(PrizeStatusEnum.WRITE_OFF_FAIL.getCode());
                rechargeResult.setStatusInfo("未找到用户支付openId");
                return rechargeResult;
            }
        }
        String mchOrderNo = IdUtil.getSnowflake().nextIdStr();
        CircleTradingClient tradingClient = new CircleTradingClient(gwAppKey, gwAppSecret, gwUrl, merchantCode);
        try {
            // todo 过渡代码，后面全面转向账户中心
            if(Long.parseLong(sceneId.replace("ACT","")) < 1534826041097474048L){
                TradingApiResult<TradingSendResult> result = tradingClient.transferWithResult(merchantAppId, amount, mchOrderNo, "wxpay",
                        "WX_CASH", payAppId, payOpenId, null, remark, null, "127.0.0.1");
                log.info("微信红包{}，{}，{}，{}发送结果:{}", openId, payAppId, payOpenId, amount, JSONUtil.toJsonStr(result));
                if (Objects.equals(result.getCode(), 0)) {
                    TradingSendResult tradingSendResult = result.getData();
                    if (Objects.equals(tradingSendResult.getState(), (byte) 2)) {
                        rechargeResult.setPrizeStatus(PrizeStatusEnum.WRITE_OFF_SUCCESS.getCode());
                    } else {
                        // 微信用户未实名的错误在这里
                        rechargeResult.setPrizeStatus(PrizeStatusEnum.WRITE_OFF_FAIL.getCode());
                        rechargeResult.setStatusInfo(tradingSendResult.getErrMsg());
                    }
                } else {
                    // 商户账户余额不足的错误在这里
                    rechargeResult.setPrizeStatus(PrizeStatusEnum.WRITE_OFF_FAIL.getCode());
                    rechargeResult.setStatusInfo(result.getMsg());
                }
                return rechargeResult;
            }

            RedPacketDto redPacketDto = new RedPacketDto();
            redPacketDto.setMchAppId(merchantAppId);
            redPacketDto.setMchNo(merchantCode);
            redPacketDto.setSceneType(EnumAccountSceneType.ACT_CENTER);
            redPacketDto.setSceneId(sceneId);
            redPacketDto.setAmount(Long.valueOf(amount));
            redPacketDto.setPayAppId(payAppId);
            redPacketDto.setPayOpenId(payOpenId);
            redPacketDto.setNickname(nickname);
            redPacketDto.setMobile(phoneNumber);
            redPacketDto.setClientIp("127.0.0.1");
            redPacketDto.setOrderNo(mchOrderNo);
            redPacketDto.setText(remark);
            redPacketDto.setGroupId(serviceGroupId);
            redPacketDto.setCallbackType(EnumCallbackType.DUBBO);
            redPacketDto.setOrderDesc(remark);
            redPacketDto.setRedPacketType(redPacketType);
            log.info("发送红包接口参数:{}", JSONUtil.toJsonStr(redPacketDto));
            RedPacketResultDto result = dubboPayAccountService.sendRedPacket(redPacketDto);
//            TradingApiResult<TradingSendResult> result = tradingClient.transferWithResult(merchantAppId, amount, mchOrderNo, "wxpay",
//                    "WX_CASH", payAppId, payOpenId, null, remark, null, "127.0.0.1");
            log.info("微信红包{}，{}，{}，{}发送结果:{}", openId, payAppId, payOpenId, amount, JSONUtil.toJsonStr(result));
//            if (Objects.equals(result.getCode(), 0)) {
            if (result != null && EnumRedPacketStatus.RECEIVE.getCode().equals(result.getState())) {
                rechargeResult.setPrizeStatus(PrizeStatusEnum.WRITE_OFF_SUCCESS.getCode());
            } else {
                // 微信用户未实名的错误在这里
                rechargeResult.setPrizeStatus(PrizeStatusEnum.WRITE_OFF_FAIL.getCode());
                rechargeResult.setStatusInfo(result != null ? result.getErrMsg() : null);
            }
//            } else {
//                // 商户账户余额不足的错误在这里
//                rechargeResult.setPrizeStatus(PrizeStatusEnum.WRITE_OFF_FAIL.getCode());
//                rechargeResult.setStatusInfo(result.getMsg());
//            }
        } catch (Exception e) {
            log.error("微信红包发送失败", e);
            rechargeResult.setPrizeStatus(PrizeStatusEnum.WRITE_OFF_FAIL.getCode());
            rechargeResult.setStatusInfo(e.getMessage());
        }
        return rechargeResult;
    }

    public RechargeResult recharge(String sceneId, String openId, Integer amount, String remark) {
        return recharge(sceneId, openId, null, null, null, null, amount, remark);
    }

}
